One of your colleagues of the past academic years, i.e. Maria Levchenko, has worked (for her thesis) on the creation of an environment to support the study of Computational Thinking and Programming
Tomorrow, 12 November 2024, she will be here, in Aula Affreschi, from 12:00 to 13:00 to introduce you the environment and allow you to use it to improve your knowledge about the course
I strongly suggest all of you to attend and to use the environment
 
					She was a computer scientist
The first programmer of the Harvard Mark I - another general purpose electromechanical computer used during the WWII
Main developer of COBOL, one of the first high-level programming languages
COBOL adopted English for commands: x IS GREATER THAN y

It is an high-level programming language for general-purpose programming
It is currently one of the most used languages for programming in the Web, for Data Science and Natural Language Processing tasks
It will be introduced with more details during the following lectures and, in particular, in the laboratory sessions
Play with Python online:
[Our first algorithm] Consider three different strings as input, i.e. two words and a bibliographic entry of a published paper. The algorithm must return: the number 2 if the bibliographic entry contains both words; the number 1 if the bibliographic entry contains only one word; the number 0 otherwise.
def <func_name>(<parameter_1>, <parameter_2>, ...)
<func_name> and <parameter_i> cannot contain spaces and cannot start with a number
def contains_word(first_word, second_word, bib_entry):
    ...
    ...
    ...All the instructions of the function must be specified in the following lines, as an indented block
A variable is a symbolic name that contains some information referred to as a value (e.g. first_word, which is a particular kind of variable, called parameter)
Partial algorithm: if the bibliographic entry contains the first word, then the number 1 is returned, otherwise 0 is returned
We need:
a mechanism to return a particular value if a specific condition is true
a way for checking if the bibliographic entry contains the input word
a command for returning the result
It allows one to execute a particular instruction if a condition is true (the if statement), while an alternative set of instructions is executed instead if the condition specified is false (the else statement, which is optional)
if <condition>:
    ...
    ...
else:
    ...
    ...The command in is used to check if a certain string is contained in another one
<string1> in <string2> would be true if the value <string1> is contained in <string2>
A string is a particular type of value that contains a sequence of characters, and it is usually defined by using the quotes – e.g. "Berners-Lee"
return <value_to_return>
The execution of a return statement finishes the execution of a function, and all the instructions that follow that statement are not processed anymore
E.g.: return 1
A number is defined by writing it down as it is – e.g. 42 and -42 for positive/negative integers, 1.625 and -1.625 for positive/negative decimals
"42" is different from 42
def contains_word(first_word, second_word, bib_entry):
    if first_word in bib_entry:
        return 1
    else:
        return 0The description of the algorithm says to return 2 if the bibliographic entry contains both the input words
A boolean can be assigned to one out of two distinct and disjoint values, True and False
E.g.: first_word in bib_entry returns a boolean value
<operator> <B1>, where <operator> can be only not
<B1> <operator> <B2>, where <operator> can be either or or and
| B1 | B2 | not B1 | B1 and B2 | B1 or B2 | 
|---|---|---|---|---|
| True | True | False | True | True | 
| True | False | False | False | True | 
| False | True | True | False | True | 
| False | False | True | False | False | 
Strings: <S1> <operator> <S2>
| S1 | S2 | S1 < S2 | S1 <= S2 | S1 > S2 | S1 >= S2 | S1 == S2 | S1 != S2 | S1 in S2 | S1 not in S2 | 
|---|---|---|---|---|---|---|---|---|---|
| "Alice" | "Bob" | True | True | False | False | False | True | False | True | 
| "Alice" | "Alice" | False | True | False | True | True | False | True | False | 
Numbers: <N1> <operator> <N2>
| N1 | N2 | N1 < N2 | N1 <= N2 | N1 > N2 | N1 >= N2 | N1 == N2 | N1 != N2 | 
|---|---|---|---|---|---|---|---|
| 3 | 4 | True | True | False | False | False | True | 
| 4 | 4 | False | True | False | True | True | False | 
def contains_word(first_word, second_word, bib_entry):
    if first_word in bib_entry and second_word in bib_entry:
        return 2
    else:
        if first_word in bib_entry or second_word in bib_entry:
            return 1
        else:
            return 0first_word in bib_entry and second_word in bib_entry used and evaluated twice
It can be avoided defining new variables: <variable_name> = <variable_value>
For instance:
contains_first_word = first_word in bib_entry
contains_second_word = second_word in bib_entry
It is possible to collapse occurrences of else statements when these contain an if statement as their first instruction
In this case, the else-if pair can be safely replaced by an elif statement
if <condition1>:
    ...
else:
    if <condition2>:
        ...
    else:
        ...if <condition1>:
    ...
elif <condition2>:
    ...
else:
    ...def contains_word(first_word, second_word, bib_entry):
    contains_first_word = first_word in bib_entry
    contains_second_word = second_word in bib_entry
    if contains_first_word and contains_second_word:
        return 2
    elif contains_first_word or contains_second_word:
        return 1
    else:
        return 0In order to be sure that the result returned by an algorithm is correct, one has to test its execution by means of some approach, e.g. by trying different kinds of input and seeing if it is behaving as expected
One of the most used and effective methods used by programmers is called Test-Driven Development (or TDD)
When one has a computational problem to solve, the first thing to develop is a test so as to check if the software to develop returns the value as expected

def test_<algorithm>(<algorithm input params>, expected):
    result = <algorithm>(<algorithm input params>)
    if result == expected:
        return True
    else:
        return False
def <algorithm>(<algorithm input params>):
    return
print(test_<algorithm>(<algorithm input params 1>, <expected_1>))
print(test_<algorithm>(<algorithm input params 2>, <expected_2>))
At the very beginning, all the instructions of the algorithm will be substituted by the instruction return, so as to allow all the new tests to fail
def test_contains_word(first_word, second_word, bib_entry, expected):
    result = contains_word(first_word, second_word, bib_entry)
    if expected == result:
        return True
    else:
        return False
def contains_word(first_word, second_word, bib_entry):
    contains_first_word = first_word in bib_entry
    contains_second_word = second_word in bib_entry
    ...
print(test_contains_word("a", "b", "abcd", 2))
print(test_contains_word("a", "b", "acde", 1))
print(test_contains_word("a", "b", "cdef", 0))
From How To Code in Python: